package com.sw.bbs.common.util;

import net.coobird.thumbnailator.Thumbnails;
import org.apache.commons.codec.binary.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.URL;
import java.net.URLConnection;

public class ImageFileUtil {

    private static final Logger logger = LoggerFactory.getLogger(ImageFileUtil.class);

    public final static String IMAGE_FORMAT = "jpg";

    private ImageFileUtil(){

    }


    /**
     * 根据图片url获取bufferimage
     * @param url
     * @return
     */
    private static BufferedImage getBufferedImageByURL(String url) {
        try {
            URL imageUrl = new URL(url);
            URLConnection urlConnection = imageUrl.openConnection();
            urlConnection.setConnectTimeout(5000);
            urlConnection.setReadTimeout(5000);
            return ImageIO.read(urlConnection.getInputStream());
        } catch (Exception e) {
            logger.warn("fail get image by url", e);
        }
        return null;
    }

    /**
     * 根据图片url获取字节数组
     * @param url
     * @return
     */
    public static byte[] getImageBytesByURL(String url) {
        BufferedImage bufferedImage = getBufferedImageByURL(url);

        if (null != bufferedImage) {

            ByteArrayOutputStream baos = null;
            try {
                baos = new ByteArrayOutputStream();
                ImageIO.write(bufferedImage, IMAGE_FORMAT, baos);
                baos.flush();
                return baos.toByteArray();
            } catch (Exception e) {
                logger.warn("fail get image by url", e);
            } finally {
                if (null != baos) {
                    try {
                        baos.close();
                    } catch (IOException e) {
                        logger.warn("fail close ByteArrayOutputStream", e);
                    }
                }
            }
        }
        return null;
    }

    /**
     * 根据图片url和人脸框 裁剪图片
     * @param url
     * @param ltx
     * @param lty
     * @param rdx
     * @param rdy
     * @return
     */
    public static byte[] getCutImageBytesByURL(String url, Integer ltx, Integer lty, Integer rdx, Integer rdy){

        BufferedImage bufferedImage = getBufferedImageByURL(url);

        if (null != bufferedImage) {
            ByteArrayOutputStream baos = null;
            try {
                baos = new ByteArrayOutputStream();
                int width = rdx - ltx;
                int height = rdy - lty;
                Thumbnails.of(bufferedImage)
                        .sourceRegion(ltx, lty, width, height)
                        .size(width, height)
                        .outputFormat(IMAGE_FORMAT)
                        .toOutputStream(baos);
                baos.flush();
                return baos.toByteArray();
            } catch (Exception e) {
                logger.warn("fail get cut image bytes by url", e);
            } finally {
                if (null != baos) {
                    try {
                        baos.close();
                    } catch (IOException e) {
                        logger.warn("fail close ByteArrayOutputStream", e);
                    }
                }
            }
        }
        return null;
    }

    /** 将base64转换成流输出
     * @param base64Str
     */
    public static byte[] getImageBytesByBase64(String base64Str)
    {
        if (StringUtils.isEmpty(base64Str)) {
            logger.error("[error]>>> base64 is null...");
            return null;
        }
        try {
            byte[] bytes = Base64.decodeBase64(base64Str);
            return bytes;
        } catch (Exception e) {
            logger.error("[error]>>> base64 transfer error...");
        }

        return null;
    }

    /**
     * 根据url获取图片base64
     * @param url
     * @return
     */
    public static String getImageBase64ByURL(String url) {
        byte[] bytes = getImageBytesByURL(url);

        if (null != bytes) {
            return Base64.encodeBase64String(bytes);
        }

        return null;
    }

    /**
     * 根据url旋转图片
     * @param url
     * @param angle
     * @return
     */
    public static byte[] getRotateImageBytesByURL(String url, double angle) {
        BufferedImage bufferedImage = getBufferedImageByURL(url);

        if (null != bufferedImage) {
            ByteArrayOutputStream baos = null;
            try {
                baos = new ByteArrayOutputStream();
                Thumbnails.of(bufferedImage)
                        .rotate(angle)
                        .outputFormat(IMAGE_FORMAT)
                        .size(bufferedImage.getWidth(), bufferedImage.getHeight())
                        .toOutputStream(baos);
                baos.flush();
                return baos.toByteArray();
            } catch (Exception e) {
                logger.warn("fail rotate image bytes by url", e);
            } finally {
                if (null != baos) {
                    try {
                        baos.close();
                    } catch (IOException e) {
                        logger.warn("fail close ByteArrayOutputStream", e);
                    }
                }
            }
        }
        return null;
    }

    /**
     * 根据base64旋转图片
     * @param base64Str
     * @param angle
     * @return
     */
    public static byte[] getRotateImageBytesByBase64(String base64Str, double angle) {

        ByteArrayOutputStream baos = null;
        try {
            BufferedImage bufferedImage = ImageIO.read(new ByteArrayInputStream(getImageBytesByBase64(base64Str)));
            baos = new ByteArrayOutputStream();
            Thumbnails.of(bufferedImage)
                    .rotate(angle)
                    .size(bufferedImage.getWidth(), bufferedImage.getHeight())
                    .outputFormat(IMAGE_FORMAT)
                    .toOutputStream(baos);
            baos.flush();
            return baos.toByteArray();
        } catch (Exception e) {
            logger.warn("fail rotate image bytes by url", e);
        } finally {
            if (null != baos) {
                try {
                    baos.close();
                } catch (IOException e) {
                    logger.warn("fail close ByteArrayOutputStream", e);
                }
            }
        }
        return null;
    }

    /**
     * 根据图片url旋转图片并获取base64
     * @param url
     * @param angle
     * @return
     */
    public static String getRotateImageBase64ByURL(String url, double angle) {
        byte[] bytes = getRotateImageBytesByURL(url, angle);

        if (null != bytes) {
            return Base64.encodeBase64String(bytes);
        }

        return null;
    }

    /**
     * 根据图片base64旋转图片并获取base64
     * @param base64Str
     * @param angle
     * @return
     */
    public static String getRotateImageBase64ByBase64(String base64Str, double angle) {
        byte[] bytes = getRotateImageBytesByBase64(base64Str, angle);

        if (null != bytes) {
            return Base64.encodeBase64String(bytes);
        }

        return null;
    }

    public static void main(String[] args) {
       String bs = ImageFileUtil.getRotateImageBase64ByURL("http://n.sinaimg.cn/sports/transform/20171105/zpwv-fynnnsc6067744.jpg", 90);
        System.out.println(bs);
    }

}
